home *** CD-ROM | disk | FTP | other *** search
- Path: j.cc.purdue.edu!mentor.cc.purdue.edu!noose.ecn.purdue.edu!samsung!uunet!papaya.bbn.com!rsalz
- From: rsalz@bbn.com (Rich Salz)
- Newsgroups: comp.sources.unix
- Subject: v23i034: Run a program under a pty session, Part04/06
- Message-ID: <2884@litchi.bbn.com>
- Date: 10 Oct 90 14:16:54 GMT
- Organization: BBN Systems and Technologies, Cambridge MA
- Lines: 1868
- Approved: rsalz@uunet.UU.NET
- X-Checksum-Snefru: cceeda5b e213dfb2 d9db214c 1b846bab
-
- Submitted-by: Dan Bernstein <brnstnd@kramden.acf.nyu.edu>
- Posting-number: Volume 23, Issue 34
- Archive-name: pty/part04
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # The tool that generated this appeared in the comp.sources.unix newsgroup;
- # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
- # Contents: COPYRIGHT QUESTIONS TESTS patch/Makefile patch/README
- # sig.c slave.c texts.c util/biff.c util/sesslist.c util/sessuser.1
- # util/sessuser.c util/sessutil.c util/write.c util/xsessutil.c
- # Wrapped by rsalz@litchi.bbn.com on Wed Oct 10 10:11:39 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 4 (of 6)."'
- if test -f 'COPYRIGHT' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'COPYRIGHT'\"
- else
- echo shar: Extracting \"'COPYRIGHT'\" \(2129 characters\)
- sed "s/^X//" >'COPYRIGHT' <<'END_OF_FILE'
- Xpty version 3.001, August 21, 1990.
- XCopyright (c) 1990, Daniel J. Bernstein.
- XAll rights reserved.
- X
- XI want this program to be distributed freely in original form.
- X
- XOnce you've received a legal copy of this program, you can use it.
- XForever. Nobody can take that right away from you. You can make changes
- Xand backup copies for your use (or, if you're an organization, for the
- Xuse of everyone in the organization). You can distribute patches (though
- Xnot patched versions). You'd have all these rights even if I didn't tell
- Xyou about them.
- X
- XCopyright law gives an author the exclusive right to copy and distribute his
- Xworks. So that you don't have to worry about these legalities, I grant you the
- Xright to make and distribute exact and complete copies of this program.
- X
- XOn the other hand, I don't want this program sold without my permission.
- XUnless I give you permission, you may not charge for copies. You may charge for
- Xdistribution---but only if you first warn the recipient that the code is free,
- Xand tell him where you got it from.
- X
- XI don't want this program distributed without my name on it. I also don't
- Xwant lots of different versions running around, so unless I give you permission
- Xyou can't send out a modified version. It's perfectly all right to send other
- Xpeople a description of how to make your changes (i.e., a patch), because then
- Xeach recipient knows firsthand what patches he's installed, and I won't go
- Xchasing ghosts. (An author has no right to control patches in any case.)
- X
- XIf you run an archive site: When you receive a patch supposedly from me, do you
- Xapply it to the original package and repackage it? I encourage you to change
- Xyour policy, if for no other reason than to give recipients a fallback in case
- Xof buggy patches. If you're really set on this, how about including the patches
- Xas separate, unapplied PATCHnn files inside the package? That's fine by me.
- X
- XIf you have questions about this program or about this notice, or if you
- Xwould like additional rights beyond those granted above, or if you have
- Xa patch that you don't mind sharing, please contact me on the Internet
- Xat brnstnd@acf10.nyu.edu.
- END_OF_FILE
- if test 2129 -ne `wc -c <'COPYRIGHT'`; then
- echo shar: \"'COPYRIGHT'\" unpacked with wrong size!
- fi
- # end of 'COPYRIGHT'
- fi
- if test -f 'QUESTIONS' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'QUESTIONS'\"
- else
- echo shar: Extracting \"'QUESTIONS'\" \(4202 characters\)
- sed "s/^X//" >'QUESTIONS' <<'END_OF_FILE'
- XI selected the questions below from articles posted to the USENET
- Xnewsgroup comp.unix.questions. All the questions are reasonably easy to
- Xanswer with pty and not too easy to answer with other widely available
- Xtools. So I hope this file is useful, and I hope other software authors
- Xadopt the QUESTIONS idea.
- X
- XOrganization: question, one-sentence answer, further details of
- Xanswer, why the question normally poses a problem, and why the answer
- Xgiven solves the problem.
- X
- X
- X1. How to redirect telnet's input?
- X
- XRun pty telnet instead of telnet. Caveat: telnet stupidly flushes its
- Xinput at connect time, so be careful not to flood it; instead do
- Xsomething like % (sleep 5;echo help;echo quit) | pty telnet whatever 25.
- X(Try it!) The five-second pause should be enough. For a more
- Xsophisticated (and reliable) technique, see #4 below.
- X
- XThe problem here is that telnet wants to take its input from a terminal.
- XMost other interactive applications (e.g., editors) feel the same way
- Xabout stdin, stdout, and stderr. pty solves this by setting input,
- Xoutput, and error all to the pseudo-terminal.
- X
- X
- X2. How to redirect su's input?
- X
- Xpty su < input, of course. (I certainly don't recommend putting your
- Xpassword in plaintext to be fed to su, but it can be done!) Note that
- Xsome su's flush their input; solve this as in #1 above or #4 below.
- X
- XThe problem is that su opens /dev/tty for its input. Many other programs
- Xuse /dev/tty explicitly for input and output; how do you redirect them?
- Xpty solves this because a program under a pseudo-terminal refers to that
- Xterminal when it opens /dev/tty.
- X
- X
- X3. How to make sed 's/foo/bar/g' | more work?
- X
- Xpty -0 sed 's/foo/bar/g' | more. You can abbreviate pty -0 as condom.
- X
- XThe problem is that sed uses stdio. stdio checks whether its output is a
- Xterminal; if not, it buffers a block of data inside the program. To see
- Xthis in action, try the original % sed 's/foo/bar/g' | more; unless you
- Xtype a lot of input, sed will keep buffering its output, so you'll never
- Xsee anything.
- X
- Xpty solves the stdio buffer problem because a program under stdio does
- Xhave a terminal (the pseudo-terminal) as output. So stdio buffers only a
- Xline at a time.
- X
- X
- X4. How to start a program, respond to its prompts, give the correct
- X replies, and catch the output?
- X
- XOn a machine with named pipes created by mknod foo p:
- X
- X #!/bin/sh
- X # Generic reader-writer.
- X (umask 077;mknod input p;mknod output p)
- X pty -0 program args < input | pty -0 tee record > output &
- X exec 4>input 5<output
- X # Now read prompts from <&5 and write replies to >&4.
- X # A transcript is kept in record.
- X
- XAnother solution is to create two (unnamed) pipes, then stick pty
- Xbetween them as above. This requires C code but is more portable.
- X
- XThe problems here are just the problems in #1-#3 above.
- X
- X
- X5. How to fool rn into processing KILL files in the background?
- X
- Xpty -T rn &. This does have one deficiency: control characters like ^C,
- X^Z, and so on affect pty rather than rn. (That's what -T does.) This
- Xdoesn't matter for rn, but pty -T vi verylongfile definitely doesn't
- Xwork the right way. To pass control characters through, start with
- X
- X % pty -s sh -c 'sessname;disconnect;pty vi verylongfile'
- X
- X(pty -s can be abbreviated as sess.) Then watch the vi process with ps
- Xor by typing pty -sT reconnect xx, watching, then pressing ^C, where xx
- Xis the session name (pty extension). When you want to reconnect and pass
- Xcontrol characters to vi, type % pty -s reconnect xx. From that point
- Xit'll feel just like a normal vi.
- X
- XThe problem is that rn---like all character-based interactive
- Xapplications---wants to change the tty mode to read one character at a
- Xtime instead of one line at a time. The tty driver doesn't let it do
- Xthis in the background. pty -T rn solves this because rn is really in
- Xthe foreground under the pty.
- X
- X
- X6. How to get terminal speed from shell script?
- X
- X"`pty stty speed`", assuming fd 0 or fd 2 is the tty.
- X
- XThe problem is that a straight `stty speed` pipes stty's output away
- Xfrom your terminal and back into your shell. Many versions of stty
- Xassume that their output points to the terminal, so they blow up. pty
- Xsolves this because it copies information from the real terminal to the
- Xpseudo-terminal.
- END_OF_FILE
- if test 4202 -ne `wc -c <'QUESTIONS'`; then
- echo shar: \"'QUESTIONS'\" unpacked with wrong size!
- fi
- # end of 'QUESTIONS'
- fi
- if test -f 'TESTS' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'TESTS'\"
- else
- echo shar: Extracting \"'TESTS'\" \(3657 characters\)
- sed "s/^X//" >'TESTS' <<'END_OF_FILE'
- X#!/bin/sh
- X# This is a shell script. Feed it to sh.
- Xecho '
- XHi, and welcome to the pty test script.
- X
- XAs in installation, I'\''m not actually going to do anything.
- XI'\''ll just guide you through a few (non-comprehensive) tests.
- X
- XRemember: Like all software, pty comes without warranty, to the extent
- Xpermitted by applicable law. Use it at your own risk.
- X'
- X
- Xecho '----- Press return to continue. ' | tr -d '\012'; read contline
- X
- Xecho '
- XFirst, just try % pty vi. You shouldn'\''t be able to tell the
- Xdifference between this and a normal vi; stopping and restarting should
- Xwork perfectly, as should normal typing.
- X'
- X
- Xecho '----- Press return to continue. ' | tr -d '\012'; read contline
- X
- Xecho '
- XNext, try % pty -0 tr \! \? | pty vi. This should work just like the
- Xlast vi, with the following differences: 1. Stopping will require two
- X^Zs, because csh idiotically doesn'\''t think a pipeline has stopped
- Xwhen just its second component stops. 2. Exiting will require an extra
- Xline to feed through tr, so that it gets a broken pipe; this is more
- Xsensible than #1. 3. All exclamation points will be turned into question
- Xmarks. This has obvious applications. :w /dev/null helps to escape.
- X'
- X
- Xecho '----- Press return to continue. ' | tr -d '\012'; read contline
- X
- Xecho '
- XContinuing along the lines of how to stick annoying programs into a
- Xpipe, try % pty -0 sed '\''s/foo/bar/g'\'' | more. (Remember that sed outputs
- Xeach line only after it receives the next.) Try the same thing without
- Xpty.
- X
- XNote that pty -0 can be abbreviated as condom.
- X'
- X
- Xecho '----- Press return to continue. ' | tr -d '\012'; read contline
- X
- Xecho '
- XNext, try using the replacement script program. % script. Type various
- Xcommands; try logging on to another terminal and using talk; observe
- Xthat you'\''re listed in /etc/utmp. Try the clones of tty, mesg, biff,
- Xu, wall, who, lock. (Try them under a non-pty session too.)
- X'
- X
- Xecho '----- Press return to continue. ' | tr -d '\012'; read contline
- X
- Xecho '
- XMuch of the fun of pty is in disconnecting and reconnecting sessions.
- XIf you'\''re ambitious, try % sess sh. ^Z will get you out and back in.
- XTry sessname without an argument; try it with an argument. Try sesslist.
- XFinally, try $ disconnect, and go on to the next part of this script.
- X'
- X
- Xecho '----- Press return to continue. ' | tr -d '\012'; read contline
- X
- Xecho '
- XAlthough it looks like your sh session has finished, it'\''s actually
- Xsitting in limbo, waiting for you to reconnect. You can still see it
- Xunder who, sesslist, or ps. Now try % sess reconnect q7 or whatever the
- Xextension of the disconnected session is; you should be right back in.
- X
- XYou can try the same thing by actually hanging up your connection, then
- Xlogging in again and reconnecting.
- X'
- X
- Xecho '----- Press return to continue. ' | tr -d '\012'; read contline
- X
- Xecho '
- XFor one final trick,
- X% sess sh
- X$ PS1=FOO.; disconnect
- X% sess sh
- X$ sesslist
- X...
- X$ PS1=BAR.; reconnect q7; disconnect
- XFOO.reconnect p4; disconnect
- XBAR.reconnect q7; disconnect
- XFOO.echo Neat, flipping right back and forth!
- X'
- X
- Xecho '----- Press return to continue. ' | tr -d '\012'; read contline
- X
- Xecho '
- XThat'\''s it! Make sure the manual pages and programs are easily
- Xaccessible. To repeat a note from INSTALL:
- X
- XIf you make it through installation and testing and get pty running,
- Xplease send a note to the author, Dan Bernstein, on the Internet
- Xat brnstnd@nyu.edu. Let him know your computer model, OS version, and
- Xwhat changes you had to make. If you have any trouble, please also get
- Xin touch with the author. If you have a different kind of system with
- Xpseudo-terminal support that could use a pty port, the author would
- Xlove to hear about it.
- X
- XThanks!
- X'
- END_OF_FILE
- if test 3657 -ne `wc -c <'TESTS'`; then
- echo shar: \"'TESTS'\" unpacked with wrong size!
- fi
- # end of 'TESTS'
- fi
- if test -f 'patch/Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'patch/Makefile'\"
- else
- echo shar: Extracting \"'patch/Makefile'\" \(2813 characters\)
- sed "s/^X//" >'patch/Makefile' <<'END_OF_FILE'
- Xtpat: tpat1
- X
- Xtpat1: igntt
- X echo '1. Get the new telnetd from ucbarpa.berkeley.edu:' 1>&2
- X echo 'This command will retrieve telnet.90.06.28.tar.Z.' 1>&2
- X echo 'To execute it, just press return.' 1>&2
- X echo 'To continue, just make tpat2 > /dev/null.' 1>&2
- X ./igntt tiocsti 'ftp -n 128.32.130.11 < TELNET.FTP'
- X
- Xtpat2: igntt
- X echo '2. Unpack telnetd:' 1>&2
- X echo 'This is self-explanatory. You may want tar xvf to see a file list.' 1>&2
- X echo 'To continue, just make tpat3 > /dev/null.' 1>&2
- X if test -f telnet.90.06.28.tar.Z ;\
- X then ./igntt tiocsti 'uncompress < telnet.90.06.28.tar.Z | tar xf -' ;\
- X else echo 'Aack! telnet.90.06.28.tar.Z doesn'\''t exist!' ;\
- X fi
- X
- Xtpat3: igntt
- X echo '3. Apply these patches, and check that they'\''re safe:' 1>&2
- X echo 'If all goes well, you should see a flood of successful patch output.' 1>&2
- X echo 'The unifdefs are to check the safety of the patches;' 1>&2
- X echo 'as you will see, the patches do nothing with USEPTY undefined.' 1>&2
- X echo 'To continue, just make tpat4 > /dev/null.' 1>&2
- X if test -d telnet.90.06.28 ;\
- X then ./igntt tiocsti 'cd telnet.90.06.28/telnetd; ' \
- X 'patch < ../../telnetd.90.06.28.patch; ' \
- X 'unifdef -UUSEPTY sys_term.c | cmp - sys_term.c.orig; ' \
- X 'unifdef -UUSEPTY telnetd.c | cmp - telnetd.c.orig; ' \
- X 'unifdef -UUSEPTY pathnames.h | cmp - pathnames.h.orig; ' \
- X 'cd ../..' ;\
- X fi
- X
- Xtpat4: igntt
- X echo '4. Check the pty pathname and fix it if necessary:' 1>&2
- X echo 'Since there is no standard like /inst for where programs go,' 1>&2
- X echo 'you had better make sure telnetd's pathnames.h is correct.' 1>&2
- X echo 'To continue, just make tpat5 > /dev/null.' 1>&2
- X ./igntt tiocsti 'grep PATH_PTY telnet.90.06.28/telnetd/pathnames.h'
- X
- Xtpat5: igntt
- X echo '5. Add sock.o and sock.h symlinks:' 1>&2
- X echo 'This is self-explanatory.' 1>&2
- X echo 'To continue, just make tpat6 > /dev/null.' 1>&2
- X ./igntt tiocsti 'ln -s ../../../sock.{h,o} telnet.90.06.28/telnetd'
- X
- Xtpat6: igntt
- X echo '6. Preparing for compile: Edit Makefile and Makefile.generic.' 1>&2
- X echo 'You must at least add -DUSEPTY to CFLAGS and sock.o to OBJS' 1>&2
- X echo 'in Makefile.generic.' 1>&2
- X echo 'telnetd isn'\''t too high on the portability scale, so you' 1>&2
- X echo 'may have to make quite a few more changes.' 1>&2
- X echo 'Anyway, make tpat7 > /dev/null to continue.' 1>&2
- X ./igntt tiocsti 'vi telnet.90.06.28/telnetd/Makefile.generic'
- X
- Xtpat7: igntt
- X echo '7. Compile!' 1>&2
- X echo 'As explained in the telnetd source documentation, you have' 1>&2
- X echo 'to provide the machine name to make. Under SunOS 4.0.3,' 1>&2
- X echo 'you can just press return here.' 1>&2
- X echo 'When and if this succeeds, go to step 8 of README.' 1>&2
- X ./igntt tiocsti '( cd telnet.90.06.28/telnetd; (date;make sun4.0) >>&Makelog ) &'
- X
- Xigntt: igntt.c
- X cc -o igntt igntt.c
- END_OF_FILE
- if test 2813 -ne `wc -c <'patch/Makefile'`; then
- echo shar: \"'patch/Makefile'\" unpacked with wrong size!
- fi
- # end of 'patch/Makefile'
- fi
- if test -f 'patch/README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'patch/README'\"
- else
- echo shar: Extracting \"'patch/README'\" \(4777 characters\)
- sed "s/^X//" >'patch/README' <<'END_OF_FILE'
- XAt the moment, the only thing here is telnetd.90.06.28.patch. It's
- Xpublic domain.
- X
- Xtelnetd.90.06.28.patch is a safe patch to the telnetd source in
- Xtelnet.90.06.28 on ucbarpa.berkeley.edu (128.32.130.11). ``Safe'' means
- Xthat every file compiles exactly the same if USEPTY is not defined;
- Xyou can apply the patch without any worry of messing up your source.
- X
- XWhat follows is an outline of how to apply the patch and enable it. A
- Xpatched telnetd uses pty to manage sessions, so that users can easily
- Xdisconnect and reconnect login sessions. You *must* have compiled file
- Xdescriptor passing into pty for this to work; telnetd needs to get the
- Xpseudo-terminal descriptors from pty. Given fd passing, though, the
- Xpatched telnetd gives you the *full* efficiency of the unpatched
- Xversion, even for reconnected sessions!
- X
- X
- XHere's what to do. If you have the tiocsti utility installed, try
- X``make > /dev/null'' in this directory; or just read through these
- Xinstructions. The usual warning: Like all software, this comes with
- Xall warranties disclaimed, to the extent permitted by applicable law.
- X
- X
- X1. Get the new telnetd:
- X
- X % ftp -n 128.32.130.11 < TELNET.FTP
- X
- X2. Unpack it:
- X
- X % uncompress < telnet.90.06.28.tar.Z | tar xf -
- X
- X3. Apply these patches, and check that they're safe:
- X
- X % cd telnet.90.06.28/telnetd
- X % patch < ../../telnetd.90.06.28.patch
- X % unifdef -UUSEPTY sys_term.c | cmp - sys_term.c.orig
- X % unifdef -UUSEPTY telnetd.c | cmp - telnetd.c.orig
- X % unifdef -UUSEPTY pathnames.h | cmp - pathnames.h.orig
- X % cd ../..
- X
- X4. Check the pty pathname and fix it if necessary:
- X
- X % grep PATH_PTY telnet.90.06.28/telnetd/pathnames.h
- X
- X5. Add sock.o and sock.h symlinks:
- X
- X % ( cd telnet.90.06.28/telnetd; ln -s ../../../sock.{o,h} . )
- X
- X6. When you want to compile the patched version: Add sock.o to OBJS
- X and -DUSEPTY to CCOPTS in Makefile.generic. Change whatever else
- X necessary to get telnetd to compile.
- X
- X7. Compile! On a Sun 4 under SunOS 4.0.3, for example, you just
- X ``make sun4.0'' in the telnetd directory.
- X
- X8. If you actually survive telnetd's incompatibilities and get it to
- X compile, keep reading.
- X
- X
- XThe reason this telnetd is so big is that it supports Linemode, a bold
- Xattempt to cut the Internet load from all the fast typists in the world
- Xby a third or even a half.
- X
- XIf you're bored, compile the telnet client as well.
- X
- X
- XAnyway, the telnetd you just compiled supports pty. You probably don't
- Xwant to replace your original telnetd, because if something goes wrong
- Xthen you need to log in again. Also, your telnetd may have special
- Xfeatures for your machine. Instead, take the gradual upgrade path: Put
- Xtelnetd into /usr/local/telnetd.pty, add a new ``tpt'' port to
- X/etc/services, and add this line to /etc/inetd.conf:
- X
- Xtpt stream tcp nowait root /usr/local/telnetd.pty telnetd
- X
- X(On older machines, ``root'' wouldn't be there; imitate the telnet line
- Xto figure out the right format. If you have the better interface of
- Xattachport, use it instead.) kill -HUP the inetd process so that it will
- Xreread inetd.conf.
- X
- X
- XNow try connecting to the tpt port rather than 23 (instead of telnet X,
- Xdo telnet X tpt). You should end up talking to the new telnetd, a clean
- Xlogin, and (best of all) a pty session. (The most common problem: Lines
- Xdon't appear until after you press return. This means that your old
- Xtelnet doesn't support Linemode; type ``^]mo ch'' to fix it. Also send
- Xcomplaints about the incompatibilities to dab@cray.com.) If the
- Xconnection hangs for more than a second or produces weird results,
- Xyou're probably out of luck; pty's author would appreciate hearing about
- Xyour experiences.
- X
- XIf all goes well (whew!) you can log in normally, just as if you're
- Xconnected to the old telnetd. Once you're in a shell, try using the pty
- Xutilities, as if you were under sess. You should find that the commands
- Xfail unless you're root, because that session was started by root rather
- Xthan you. (This points out a failure in the telnetd-login-utmp model.)
- XTo gain control of the session, type ``sessuser'' and pray. If nothing
- Xgoes wrong, you can then disconnect the session, set up a reconnect to
- Xanother one, use sessname and sesslist, etc. Yahoo! Tell your users!
- XReplace your old telnetd with the new one! Add sessuser to the default
- X.cshrc! And please send a note to brnstnd@nyu.edu about your success.
- X
- X
- XNote that many popular versions of login use an annoying heuristic to
- Xsave a few microseconds in updating /etc/utmp. The result is, first,
- Xthat there's a race condition that can break down /etc/utmp on heavily
- Xloaded machines; and second, that login and pty have different views of
- X/etc/utmp. For this reason, pty is invoked with -xR to search for ptys
- Xin order. You may even want to make -xR default (by setting flagxrandom
- Xto 0 in pty's globals.c). Sigh.
- END_OF_FILE
- if test 4777 -ne `wc -c <'patch/README'`; then
- echo shar: \"'patch/README'\" unpacked with wrong size!
- fi
- # end of 'patch/README'
- fi
- if test -f 'sig.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'sig.c'\"
- else
- echo shar: Extracting \"'sig.c'\" \(4549 characters\)
- sed "s/^X//" >'sig.c' <<'END_OF_FILE'
- X/* Copyright 1990, Daniel J. Bernstein. All rights reserved. */
- X
- X#include "config.h"
- X#include <sys/time.h>
- X#include "sig.h"
- X
- X/* This is a stripped-down signal library, with automatic critical */
- X/* sections around every signal handler. As long as no signal handler */
- X/* has to pause waiting for another signal, this works beautifully */
- X/* and prevents all races. */
- X
- Xstatic int queued[SIGNUM];
- Xstatic int quo[SIGNUM];
- Xstatic sig_syshandler orig[SIGNUM];
- Xstatic sig_handler handler[SIGNUM];
- X
- Xstatic sig_syshandler signalv(s,h)
- Xregister sig_num s;
- Xregister sig_syshandler h;
- X{
- X return signal(s,h);
- X}
- X
- Xstatic int crit = 0;
- X
- Xstatic void handle(i)
- Xregister sig_num i;
- X{
- X if (crit)
- X queued[i] = 1;
- X else
- X {
- X register int q;
- X register sig_num j;
- X
- X crit = 1; (void) handler[i](i); queued[i] = 0; crit = 0;
- X do for (j = q = 0;j < SIGNUM;j++) if (queued[j])
- X {
- X crit = q = 1;
- X if (j != i) (void) handler[j](j);
- X queued[j] = 0; crit = 0;
- X }
- X while (q);
- X }
- X}
- X
- X/* To see why handle() works: First, crit can be considered a local
- Xvariable, because handle() is the only routine that modifies it, and
- Xhandle() always leaves crit the same. Second, crit is 1 while any
- Xhandler is called, and then any simultaneous handle()s will simply
- Xqueue. Hence handlers are mutually exclusive. Third, when handle() is
- Xcalled with crit == 0, it can only exit after going through an entire j
- Xloop with no queued[]s true. Fourth, if all queued[]s are false through
- Xthat j loop, then crit is not set by handle() during that loop. Finally,
- Xif crit is 0, handle() will exit with no queued signals: this is true by
- Xinduction from the previous observations. */
- X
- X
- X/* There is unfortunately no guarantee that a signal handler as */
- X/* passed to signal() will receive its signal number as its first */
- X/* argument. We do make that guarantee. */
- X
- X#define HAN(s,h) SIGRET_TYPE h() { handle(s); }
- X
- XHAN(0,han0); HAN(1,han1); HAN(2,han2); HAN(3,han3);
- XHAN(4,han4); HAN(5,han5); HAN(6,han6); HAN(7,han7);
- XHAN(8,han8); HAN(9,han9); HAN(10,han10); HAN(11,han11);
- XHAN(12,han12); HAN(13,han13); HAN(14,han14); HAN(15,han15);
- XHAN(16,han16); HAN(17,han17); HAN(18,han18); HAN(19,han19);
- XHAN(20,han20); HAN(21,han21); HAN(22,han22); HAN(23,han23);
- XHAN(24,han24); HAN(25,han25); HAN(26,han26); HAN(27,han27);
- XHAN(28,han28); HAN(29,han29); HAN(30,han30); HAN(31,han31);
- X
- Xstatic sig_syshandler han[32] =
- X { han0 ,han1 ,han2 ,han3 ,han4 ,han5 ,han6 ,han7 ,
- X han8 ,han9 ,han10,han11,han12,han13,han14,han15,
- X han16,han17,han18,han19,han20,han21,han22,han23,
- X han24,han25,han26,han27,han28,han29,han30,han31
- X } ;
- X
- X#define QUE(s,h) SIGRET_TYPE h() { quo[s] = 1; }
- X
- XQUE(0,que0); QUE(1,que1); QUE(2,que2); QUE(3,que3);
- XQUE(4,que4); QUE(5,que5); QUE(6,que6); QUE(7,que7);
- XQUE(8,que8); QUE(9,que9); QUE(10,que10); QUE(11,que11);
- XQUE(12,que12); QUE(13,que13); QUE(14,que14); QUE(15,que15);
- XQUE(16,que16); QUE(17,que17); QUE(18,que18); QUE(19,que19);
- XQUE(20,que20); QUE(21,que21); QUE(22,que22); QUE(23,que23);
- XQUE(24,que24); QUE(25,que25); QUE(26,que26); QUE(27,que27);
- XQUE(28,que28); QUE(29,que29); QUE(30,que30); QUE(31,que31);
- X
- Xstatic sig_syshandler que[32] =
- X { que0 ,que1 ,que2 ,que3 ,que4 ,que5 ,que6 ,que7 ,
- X que8 ,que9 ,que10,que11,que12,que13,que14,que15,
- X que16,que17,que18,que19,que20,que21,que22,que23,
- X que24,que25,que26,que27,que28,que29,que30,que31
- X } ;
- X
- X
- Xvoid sig_init()
- X{
- X sig_num i;
- X
- X for (i = 0;i < SIGNUM;i++)
- X quo[i] = 0;
- X for (i = 0;i < SIGNUM;i++)
- X orig[i] = signalv(i,que[i]);
- X}
- X
- Xvoid sig_restore()
- X{
- X sig_num i;
- X
- X for (i = 0;i < SIGNUM;i++)
- X (void) signalv(i,orig[i]);
- X}
- X
- Xvoid sig_handle(s)
- Xsig_num s;
- X{
- X if (quo[s])
- X han[s]();
- X (void) signalv(s,han[s]);
- X quo[s] = 0;
- X}
- X
- Xvoid sig_ignore(s)
- Xsig_num s;
- X{
- X (void) signalv(s,SIG_IGN);
- X}
- X
- Xvoid sig_default(s)
- Xsig_num s;
- X{
- X (void) signalv(s,SIG_DFL);
- X}
- X
- Xvoid sig_sethandler(s,h)
- Xsig_num s;
- Xsig_handler h;
- X{
- X handler[s] = h;
- X}
- X
- X#ifdef SIGINTERRUPT
- Xvoid sig_interrupt()
- X{
- X register sig_num s;
- X
- X for (s = 0;s < SIGNUM;s++)
- X (void) siginterrupt(s,1);
- X}
- X#endif
- X
- Xvoid sig_startring()
- X{
- X struct itimerval it;
- X
- X it.it_value.tv_sec = it.it_interval.tv_sec = 0;
- X it.it_value.tv_usec = it.it_interval.tv_usec = 10000;
- X (void) setitimer(ITIMER_REAL,&it,(struct itimerval *) 0);
- X}
- X
- Xvoid sig_stopring()
- X{
- X struct itimerval it;
- X
- X it.it_value.tv_sec = it.it_interval.tv_sec = 0;
- X it.it_value.tv_usec = it.it_interval.tv_usec = 0;
- X (void) setitimer(ITIMER_REAL,&it,(struct itimerval *) 0);
- X}
- X
- X/*ARGSUSED*/
- Xvoid nothing(i)
- Xsig_num i;
- X{
- X ; /* that's right, absolutely nothing. */
- X}
- END_OF_FILE
- if test 4549 -ne `wc -c <'sig.c'`; then
- echo shar: \"'sig.c'\" unpacked with wrong size!
- fi
- # end of 'sig.c'
- fi
- if test -f 'slave.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'slave.c'\"
- else
- echo shar: Extracting \"'slave.c'\" \(2687 characters\)
- sed "s/^X//" >'slave.c' <<'END_OF_FILE'
- X/* Copyright 1990, Daniel J. Bernstein. All rights reserved. */
- X
- X#include "file.h"
- X#include "config.h"
- X#include "pty.h"
- X#include "tty.h"
- X#include "err.h"
- X#include "sig.h"
- X#include "slave.h"
- X#include "logs.h"
- X
- Xvoid slave(fnsty,arg)
- Xchar *fnsty;
- Xchar **arg;
- X{
- X sig_ignore(SIGTTOU);
- X sig_ignore(SIGTTIN);
- X
- X if (fdtty > -1)
- X {
- X (void) tty_dissoc(fdtty); /* must succeed */
- X (void) close(fdtty);
- X }
- X if (fdre > -1)
- X (void) close(fdre);
- X (void) close(fdin);
- X (void) close(fdout);
- X (void) close(fdmty);
- X (void) close(fdsty);
- X (void) close(0);
- X (void) close(1);
- X if (flagsameerr < 2)
- X (void) close(2);
- X if (flagsameerr < 1)
- X {
- X (void) close(3);
- X for (fdout = getdtablesize();fdout > 3;fdout--)
- X (void) close(fdout);
- X }
- X
- X if (open(fnsty,O_RDONLY) != 0)
- X fatalerrp(1,"pty: fatal: cannot reopen pty for input",errno);
- X if (open(fnsty,O_WRONLY) != 1)
- X fatalerrp(1,"pty: fatal: cannot reopen pty for output",errno);
- X if (flagsameerr < 2)
- X if (open(fnsty,(flagxerrwo ? O_WRONLY : O_RDWR)) != 2)
- X fatalerrp(1,"pty: fatal: cannot reopen pty for stderr",errno);
- X if (flagsameerr < 1)
- X if (open("/dev/tty",O_RDWR) != 3)
- X fatalerrp(1,"pty: fatal: cannot reopen pty for /dev/tty",errno);
- X
- X if ((fdtty = open("/dev/tty",O_RDWR)) == -1)
- X fatalerrp(1,"pty: fatal: cannot reopen pty for temporary /dev/tty",errno);
- X
- X if (setpgrp(0,getpid()) == -1)
- X fatalerr(1,"pty: fatal: cannot set process group\n");
- X if (tty_setpgrp(fdtty,getpid()) == -1)
- X fatalerrp(1,"pty: fatal: cannot set pty process group",errno);
- X if (tty_setmodes(fdtty,&tmopty) == -1)
- X fatalerr(1,"pty: fatal: cannot set pty modes\n");
- X if (flagxexcl)
- X if (tty_setexcl(fdtty) == -1)
- X fatalerr(1,"pty: fatal: cannot set exclusive use on pty\n");
- X
- X (void) fchmod(0,USEDPTYMODE);
- X
- X if (flagxchown)
- X (void) fchown(0,uid,PTYGROUP);
- X
- X (void) close(fdtty);
- X
- X date = now(); /* could use original date instead */
- X
- X if (flagxutmp)
- X {
- X if (flagverbose)
- X warnerr2("%s","pty: writing utmp entry\n");
- X if (utmp(fnsty + PTYUTMP_OFFSET,username,PTYUTMP_HOST,date) == -1)
- X warnerr2("pty: warning: cannot write %s utmp entry\n",fnsty);
- X }
- X
- X if (flagxwtmp)
- X {
- X if (flagverbose)
- X warnerr2("%s","pty: writing wtmp entry\n");
- X if (wtmp(fnsty + PTYWTMP_OFFSET,username,PTYWTMP_HOST,date) == -1)
- X warnerr2("pty: warning: cannot write %s wtmp entry\n",fnsty);
- X }
- X
- X if (setreuid(uid,uid) == -1)
- X /* We absolutely refuse to exec while setuid. */
- X fatalerrp(1,"pty: fatal: cannot setreuid",errno);
- X
- X sig_restore();
- X if (flagverbose)
- X warnerr2("pty: executing program %s\n",arg[0]);
- X (void) execvp(arg[0],arg);
- X fatalerr2p(1,"pty: fatal: cannot execute %s",arg[0],errno);
- X /*NOTREACHED*/
- X}
- END_OF_FILE
- if test 2687 -ne `wc -c <'slave.c'`; then
- echo shar: \"'slave.c'\" unpacked with wrong size!
- fi
- # end of 'slave.c'
- fi
- if test -f 'texts.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'texts.c'\"
- else
- echo shar: Extracting \"'texts.c'\" \(3819 characters\)
- sed "s/^X//" >'texts.c' <<'END_OF_FILE'
- X/* Copyright 1990, Daniel J. Bernstein. All rights reserved. */
- X
- X#include "config.h"
- X#include "texts.h"
- X
- Xchar *ptyauthor[] = {
- X"pty was written by Daniel J. Bernstein." ,
- X"Internet address: brnstnd@acf10.nyu.edu." ,
- X0 } ;
- X
- Xchar *ptyversion[] = {
- X"pty version 3.001, August 21, 1990." ,
- X"Copyright (c) 1990, Daniel J. Bernstein." ,
- X"All rights reserved." ,
- X0 } ;
- X
- Xchar *ptycopyright[] = {
- X"pty version 3.001, August 21, 1990." ,
- X"Copyright (c) 1990, Daniel J. Bernstein." ,
- X"All rights reserved." ,
- X"" ,
- X"I want this program to be distributed freely in original form." ,
- X"" ,
- X"Once you've received a legal copy of this program, you can use it." ,
- X"Forever. Nobody can take that right away from you. You can make changes" ,
- X"and backup copies for your use (or, if you're an organization, for the" ,
- X"use of everyone in the organization). You can distribute patches (though" ,
- X"not patched versions). You'd have all these rights even if I didn't tell" ,
- X"you about them." ,
- X"" ,
- X"I do grant you further rights, as detailed in the source package. Don't" ,
- X"worry about them unless you're planning to distribute further copies." ,
- X"" ,
- X"If you have questions about this program or about this notice, or if you" ,
- X"would like additional rights beyond those granted above, or if you have" ,
- X"a patch that you don't mind sharing, please contact me on the Internet" ,
- X"at brnstnd@acf10.nyu.edu." ,
- X0 } ;
- X
- Xchar *ptywarranty[] = {
- X"Daniel J. Bernstein disclaims all warranties to the extent permitted" ,
- X"by applicable law. He is not and shall not be liable for any damages" ,
- X"arising from the use of this program. This disclaimer shall be governed" ,
- X"by the laws of the state of New York." ,
- X"" ,
- X"In other words, use this program at your own risk." ,
- X"" ,
- X"If you have questions about this program or about this disclaimer of" ,
- X"warranty, please feel free to contact me at brnstnd@acf10.nyu.edu on" ,
- X"the Internet." ,
- X0 } ;
- X
- Xchar *ptyusage[] = {
- X"Usage: pty [ -qQve3EdDjJsStT0FACHUVW ] [ -fn ] [ -p[cCdDeEnNrRsS0] ]" ,
- X" [ -x[cCeEnNoOrRsSuUwWxX ] program [ arg ... ]" ,
- X"Help: pty -H" ,
- X0 } ;
- X
- Xchar *ptyhelp[] = {
- X"pty runs a program under a pseudo-terminal session." ,
- X"pty -ACHUVW: print authorship notice, copyright notice, this notice," ,
- X" short usage summary, version number, disclaimer of warranty" ,
- X"pty [-qQve3EdDjJsStT0F] [-fn] [-p[cCdDeEnNrRsS0]] [-x[cCeEnNoOrRsSuUwWxX]]" ,
- X" program [arg...]: run program under a pseudo-terminal" ,
- X"Options processed l to r. Capitals turn things off. Here + means default." ,
- X"-q: quiet (nothing on stderr) -e: leave fds 2 & 3 0=eSTp0 p0=pcrEN" ,
- X"+Q: normal level of verbosity -3: leave fd 3 only d=dJT D=Djt d=>T" ,
- X"-v: complain about everything +E: 2 & 3 both->pty s=sxu S=SxU s=>E" ,
- X"-d: we are detached +j: job control +t: change orig tty to char mode" ,
- X"+D: we have ctrl tty -J: ignore stops -T: leave orig tty alone" ,
- X"-s: session (allow disconnect & reconnect) -fn: pass pty fds up fd n" ,
- X"+S: no session: disconnect will send HUP +F: no -f" ,
- X"-p[cCdDeEnNrRsS]: set pty modes; defaults taken from original tty if -D" ,
- X" c: cbreak, character mode +n: change return to newline +e: echo" ,
- X" +d: new line discipline r: raw, no keyboard signals +s: screen, crt" ,
- X"-x[cCeEnNoOrRsSuUwWxX]: security/experimental/extended, may be restricted" ,
- X" c: change pty owner e: pty's stderr write-only x: set TIOCEXCL" ,
- X" +s: setuid, safer +n: check if anyone has pty open u: use /etc/utmp" ,
- X" +r: pick random pty o: skip if anyone has pty open w: use /etc/wtmp" ,
- X"If you have questions about or suggestions for pty, please feel free" ,
- X"to contact the author, Daniel J. Bernstein, at brnstnd@acf10.nyu.edu" ,
- X"on the Internet." ,
- X0 } ;
- X/* I still can't believe ptyhelp fits. :-) */
- END_OF_FILE
- if test 3819 -ne `wc -c <'texts.c'`; then
- echo shar: \"'texts.c'\" unpacked with wrong size!
- fi
- # end of 'texts.c'
- fi
- if test -f 'util/biff.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'util/biff.c'\"
- else
- echo shar: Extracting \"'util/biff.c'\" \(1038 characters\)
- sed "s/^X//" >'util/biff.c' <<'END_OF_FILE'
- X/* Public domain. */
- X
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <stdio.h>
- X#include "sessutil.h"
- Xextern unsigned short getuid();
- X
- X#define FOO (void) fstat(0,&st); \
- Xif (which) (void) fchmod(0,(int) (st.st_mode | 0100)); \
- Xelse (void) fchmod(0,(int) (st.st_mode & ~0100));
- X
- Xmain(argc,argv)
- Xint argc;
- Xchar *argv[];
- X{
- X struct stat st;
- X struct pty_session ps;
- X int uid;
- X int which;
- X
- X uid = getuid();
- X
- X if (argc == 1)
- X {
- X (void) setreuid(uid,uid);
- X (void) fstat(0,&st);
- X if (st.st_mode & 0100)
- X (void) printf("is y\n");
- X else
- X (void) printf("is n\n");
- X }
- X else
- X {
- X switch(argv[1][0])
- X {
- X case 'y': which = 1; break;
- X case 'n': which = 0; break;
- X default: (void) fprintf(stderr,"usage: biff [y] [n]\n"); exit(1);
- X }
- X if (pty_get_sess(0,uid,&ps) == -1)
- X {
- X (void) setreuid(uid,uid);
- X FOO
- X }
- X else
- X if (ps.uid != uid)
- X (void) fprintf(stderr,"not your session\n");
- X else
- X {
- X FOO
- X (void) setreuid(uid,uid);
- X FOO
- X }
- X }
- X (void) exit(0);
- X}
- END_OF_FILE
- if test 1038 -ne `wc -c <'util/biff.c'`; then
- echo shar: \"'util/biff.c'\" unpacked with wrong size!
- fi
- # end of 'util/biff.c'
- fi
- if test -f 'util/sesslist.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'util/sesslist.c'\"
- else
- echo shar: Extracting \"'util/sesslist.c'\" \(2102 characters\)
- sed "s/^X//" >'util/sesslist.c' <<'END_OF_FILE'
- X/* Public domain. */
- X
- X#include <sys/types.h>
- X#include <sys/file.h>
- X#ifdef BSD
- X#include <limits.h>
- X#endif
- X#include <sys/dir.h>
- X#include <stdio.h>
- X#include "sessutil.h"
- Xextern unsigned short getuid();
- X
- Xmain()
- X{
- X int uid;
- X DIR *dirp;
- X struct direct *dp;
- X int fd;
- X int intbuf[100];
- X char *buf = (char *) intbuf;
- X int r;
- X
- X uid = getuid();
- X
- X if (pty_sessdir(uid) == -1)
- X {
- X (void) fputs("sesslist: fatal: cannot change to session directory\n",stderr);
- X (void) exit(1);
- X }
- X dirp = opendir(".");
- X while (dp = readdir(dirp))
- X {
- X if (!strncmp(dp->d_name,"re.",3))
- X (void) printf("session %s disconnected\n",dp->d_name + 3);
- X else if (!strncmp(dp->d_name,"sess.",5))
- X {
- X if ((fd = open(dp->d_name,O_RDONLY)) == -1)
- X (void) fprintf(stderr,
- X "sesslist: warning: cannot open %s\n",dp->d_name);
- X else
- X {
- X r = read(fd,buf,99); /* anything up to sizeof(intbuf) - 1 */
- X if (r < 4 * sizeof(int))
- X (void) fprintf(stderr,
- X "sesslist: warning: cannot read %s\n",dp->d_name);
- X else if (r == 4 * sizeof(int))
- X (void) printf("session %s sigler %d master %d slave %d\n",
- X dp->d_name + 5,intbuf[1],intbuf[2],intbuf[3]);
- X else
- X {
- X buf[r] = '\0';
- X (void) printf("session %s sigler %d master %d slave %d: %s\n",
- X dp->d_name + 5,intbuf[1],intbuf[2],intbuf[3],
- X buf + 4 * sizeof(int));
- X }
- X (void) close(fd);
- X }
- X }
- X else if (!strncmp(dp->d_name,"sig.",4))
- X {
- X if ((fd = open(dp->d_name,O_RDONLY)) == -1)
- X (void) fprintf(stderr,
- X "sesslist: warning: cannot open %s\n",dp->d_name);
- X else
- X {
- X r = read(fd,buf,99);
- X if (r < 9)
- X (void) fprintf(stderr,
- X "sesslist: warning: cannot read %s\n",dp->d_name);
- X else
- X {
- X buf[r] = '\0';
- X (void) printf("session %s will drop into session %s\n",
- X dp->d_name + 4,buf + 8);
- X }
- X (void) close(fd);
- X }
- X }
- X else if (!strncmp(dp->d_name,".",1))
- X ;
- X else if (!strncmp(dp->d_name,"..",2))
- X ;
- X else
- X (void) fprintf(stderr,
- X "sesslist: warning: unknown file type %s\n",dp->d_name);
- X }
- X (void) exit(0);
- X}
- END_OF_FILE
- if test 2102 -ne `wc -c <'util/sesslist.c'`; then
- echo shar: \"'util/sesslist.c'\" unpacked with wrong size!
- fi
- # end of 'util/sesslist.c'
- fi
- if test -f 'util/sessuser.1' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'util/sessuser.1'\"
- else
- echo shar: Extracting \"'util/sessuser.1'\" \(2006 characters\)
- sed "s/^X//" >'util/sessuser.1' <<'END_OF_FILE'
- X.TH sessuser 1
- X.SH NAME
- Xsessuser \- rectify ownership of current pty session
- X.SH SYNOPSIS
- X.B sessuser
- X.SH DESCRIPTION
- X.I sessuser
- Xtransfers ownership of the current pty session
- Xto the user who owns the actual pseudo-terminal file.
- X.PP
- X.I sessuser
- Xis useful in adapting
- X.I pty
- Xto old, inconsistent models of logging in.
- XAn incoming user should be forced to type
- Xa correct password before the login process
- Xeven touches a terminal;
- Xhe should be given a tty
- Xonly after his identity is established.
- XInstead,
- Xusers are given terminals
- X(as root)
- Xfirst.
- XWhen
- Xthese obsolete programs are modified
- Xto let
- X.I pty
- Xallocate a pseudo-terminal,
- Xtheir order of operations is still the same,
- Xand
- X.I pty
- Xstill thinks the session is owned by root.
- XHowever,
- Xthe login program
- Xdoes change the ownership of the
- Xpseudo-terminal file to the user.
- X.I sessuser
- Xcommunicates this change to
- Xthe
- X.I pty
- Xmanager,
- Xso that
- X.I sesslist,
- X.I sessname,
- X.I sesskill,
- X.I disconnect,
- Xand
- X.I reconnect
- Xwill work.
- X.PP
- X.I xsessuser
- Xis just like
- X.I sessuser
- Xbut applies to sessions started with
- X.B\-xS.
- XIt should never be needed, but it is
- Xprovided for consistency.
- X.SH DIAGNOSTICS
- X.TP
- X.I cannot find session
- XThe standard input to
- X.I sessuser
- Xis not a session owned by
- Xthe effective uid of
- X.I sessuser.
- X.TP
- X.I cannot stat tty
- XThis cannot happen.
- X.TP
- X.I you don't own tty
- XYou don't own the pseudo-terminal file.
- X.TP
- X.I not child of session slave
- XThe parent to
- X.I sessuser
- Xis not the head process in the session.
- X.TP
- X.I cannot find your username
- XYou're not listed in
- X/etc/passwd.
- X.TP
- X.I cannot open /etc/utmp
- XSelf-explanatory.
- X.TP
- X.I cannot set session
- X.I sessuser
- Xis unable to record the
- Xchange in session ownership.
- X.TP
- X.I cannot communicate new user
- X.I sessuser
- Xis unable to communicate with
- Xthe pseudo-terminal
- Xmanager.
- X.SH RESTRICTIONS
- X.I sessuser
- Xrequires that the session be
- Xlisted in
- X/etc/utmp.
- XIf it is not,
- Xor if it is not listed under
- Xthe correct username,
- X.I sessuser
- Xwill exit silently
- Xwith exit code 1.
- X.SH "SEE ALSO"
- Xpty(1),
- Xsess(1)
- END_OF_FILE
- if test 2006 -ne `wc -c <'util/sessuser.1'`; then
- echo shar: \"'util/sessuser.1'\" unpacked with wrong size!
- fi
- # end of 'util/sessuser.1'
- fi
- if test -f 'util/sessuser.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'util/sessuser.c'\"
- else
- echo shar: Extracting \"'util/sessuser.c'\" \(1872 characters\)
- sed "s/^X//" >'util/sessuser.c' <<'END_OF_FILE'
- X/* Public domain. */
- X
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <stdio.h>
- X#include <utmp.h>
- X#include <pwd.h>
- X#include <signal.h>
- X#include <strings.h>
- X#include "sessutil.h"
- Xextern unsigned short getuid();
- Xextern unsigned short geteuid();
- X#define PTYUTMP_FILE "/etc/utmp"
- X
- Xmain()
- X{
- X struct pty_session ps;
- X int uid;
- X int euid;
- X register FILE *fi;
- X struct utmp ut;
- X struct stat st;
- X struct passwd *pw;
- X char *username;
- X
- X uid = getuid();
- X euid = geteuid();
- X
- X if (pty_get_sess(0,euid,&ps) == -1) /* i.e., as root */
- X {
- X (void) fputs("sessuser: fatal: cannot find session\n",stderr);
- X (void) exit(1);
- X }
- X if (fstat(0,&st) == -1)
- X {
- X (void) fputs("sessuser: fatal: cannot stat tty\n",stderr);
- X (void) exit(1);
- X }
- X if (st.st_uid != uid)
- X {
- X (void) fputs("sessuser: fatal: you don't own tty\n",stderr);
- X (void) exit(1);
- X }
- X if (ps.slavepid != getppid())
- X {
- X (void) fputs("sessuser: fatal: not child of session slave\n",stderr);
- X (void) exit(1);
- X }
- X if (!(pw = getpwuid(uid)))
- X {
- X (void) fputs("sessuser: fatal: cannot find your username\n",stderr);
- X (void) exit(1);
- X }
- X username = pw->pw_name;
- X if (!(fi = fopen(PTYUTMP_FILE,"r")))
- X {
- X (void) perror("sessuser: fatal: cannot open /etc/utmp");
- X (void) exit(1);
- X }
- X else
- X while (fread((char *) &ut,sizeof(ut),1,fi))
- X if ((ut.ut_line[3] == ps.ext1) && (ut.ut_line[4] == ps.ext2)
- X &&(ut.ut_line[5] == '\0'))
- X if (!strncmp(ut.ut_name,username,8))
- X {
- X ps.uid = uid;
- X if (pty_set_sess(0,uid,&ps) == -1)
- X {
- X (void) fputs("sessuser: fatal: cannot set session\n",stderr);
- X (void) exit(1);
- X }
- X if (kill(ps.masterpid,SIGUSR2) == -1)
- X {
- X (void) fputs("sessuser: fatal: cannot communicate new user\n",stderr);
- X (void) exit(1);
- X }
- X (void) fchown(0,euid,-1);
- X (void) exit(0);
- X }
- X else
- X (void) exit(1);
- X (void) exit(1);
- X}
- END_OF_FILE
- if test 1872 -ne `wc -c <'util/sessuser.c'`; then
- echo shar: \"'util/sessuser.c'\" unpacked with wrong size!
- fi
- # end of 'util/sessuser.c'
- fi
- if test -f 'util/sessutil.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'util/sessutil.c'\"
- else
- echo shar: Extracting \"'util/sessutil.c'\" \(3786 characters\)
- sed "s/^X//" >'util/sessutil.c' <<'END_OF_FILE'
- X/* Public domain. */
- X
- X#include "sessutil.h"
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <sys/file.h>
- X#ifdef BSD
- X#include <limits.h>
- X#endif
- X#include <stdio.h>
- Xextern char *ttyname();
- Xextern long lseek();
- X
- X/* Will have to change ttyn indices if DEVSTY changes. */
- X
- Xint pty_sessdir(uid)
- Xint uid;
- X{
- X char foo[50];
- X
- X (void) sprintf(foo,"/usr/etc/pty/%d",uid);
- X return chdir(foo);
- X}
- X
- Xint pty_get_sess(fd,uid,ps)
- Xint fd;
- Xint uid;
- Xstruct pty_session *ps;
- X{
- X char *ttyn;
- X
- X if (ttyn = ttyname(fd))
- X return pty_get_sessbyext(ttyn[8],ttyn[9],uid,ps);
- X return -1;
- X}
- X
- Xint pty_get_sessbyext(ext1,ext2,uid,ps)
- Xchar ext1;
- Xchar ext2;
- Xint uid;
- Xstruct pty_session *ps;
- X{
- X char foo[50];
- X int fdsess;
- X
- X ps->ext1 = ext1;
- X ps->ext2 = ext2;
- X (void) sprintf(foo,"/usr/etc/pty/%d/sess.%c%c",uid,ps->ext1,ps->ext2);
- X if ((fdsess = open(foo,O_RDONLY)) != -1)
- X {
- X if ((read(fdsess,(char *) &ps->uid,sizeof(int)) == sizeof(int))
- X &&(read(fdsess,(char *) &ps->siglerpid,sizeof(int)) == sizeof(int))
- X &&(read(fdsess,(char *) &ps->masterpid,sizeof(int)) == sizeof(int))
- X &&(read(fdsess,(char *) &ps->slavepid,sizeof(int)) == sizeof(int)))
- X {
- X (void) close(fdsess);
- X return 0;
- X }
- X (void) close(fdsess);
- X }
- X return -1;
- X}
- X
- Xint pty_set_sess(fd,uid,ps)
- Xint fd;
- Xint uid;
- Xstruct pty_session *ps;
- X{
- X char *ttyn;
- X char foo[50];
- X int fdsess;
- X
- X if (ttyn = ttyname(fd))
- X {
- X ps->ext1 = ttyn[8];
- X ps->ext2 = ttyn[9];
- X (void) sprintf(foo,"/usr/etc/pty/%d/sess.%c%c",uid,ps->ext1,ps->ext2);
- X if ((fdsess = open(foo,O_WRONLY)) != -1)
- X {
- X if ((write(fdsess,(char *) &ps->uid,sizeof(int)) == sizeof(int))
- X &&(write(fdsess,(char *) &ps->siglerpid,sizeof(int)) == sizeof(int))
- X &&(write(fdsess,(char *) &ps->masterpid,sizeof(int)) == sizeof(int))
- X &&(write(fdsess,(char *) &ps->slavepid,sizeof(int)) == sizeof(int)))
- X {
- X (void) close(fdsess);
- X return 0;
- X }
- X (void) close(fdsess);
- X }
- X }
- X return -1;
- X}
- X
- Xint pty_get_sessname(fd,uid,buf,len)
- Xint fd;
- Xint uid;
- Xchar *buf;
- Xint len;
- X{
- X char *ttyn;
- X char foo[50];
- X int fdsess;
- X int r;
- X
- X if (ttyn = ttyname(fd))
- X {
- X (void) sprintf(foo,"/usr/etc/pty/%d/sess.%c%c",uid,ttyn[8],ttyn[9]);
- X if ((fdsess = open(foo,O_RDONLY)) != -1)
- X {
- X if (lseek(fdsess,(long) (4 * sizeof(int)),0) != (long) -1)
- X if ((r = read(fdsess,buf,len - 1)) > 0)
- X { /* could make that != -1. This way, default session is unnamed. */
- X buf[r] = '\0';
- X (void) close(fdsess);
- X return 0;
- X }
- X (void) close(fdsess);
- X }
- X }
- X return -1;
- X}
- X
- Xint pty_set_sessname(fd,uid,buf,len)
- Xint fd;
- Xint uid;
- Xchar *buf;
- Xint len;
- X{
- X char *ttyn;
- X char foo[50];
- X int fdsess;
- X
- X if (ttyn = ttyname(fd))
- X {
- X (void) sprintf(foo,"/usr/etc/pty/%d/sess.%c%c",uid,ttyn[8],ttyn[9]);
- X if ((fdsess = open(foo,O_WRONLY)) != -1)
- X {
- X if (lseek(fdsess,(long) (4 * sizeof(int)),0) != (long) -1)
- X if (write(fdsess,buf,len) != -1)
- X {
- X (void) close(fdsess);
- X return 0;
- X }
- X (void) close(fdsess);
- X }
- X }
- X return -1;
- X}
- X
- Xint pty_get_rebyext(ext1,ext2,uid)
- Xchar ext1;
- Xchar ext2;
- Xint uid;
- X{
- X char foo[50];
- X struct stat st;
- X
- X (void) sprintf(foo,"/usr/etc/pty/%d/re.%c%c",uid,ext1,ext2);
- X return stat(foo,&st);
- X}
- X
- Xint pty_set_sig(ext1,ext2,uid,ps)
- Xchar ext1;
- Xchar ext2;
- Xint uid;
- Xstruct pty_session *ps;
- X{
- X char foo[50];
- X int fdsig;
- X
- X (void) sprintf(foo,"/usr/etc/pty/%d/sig.%c%c",uid,ps->ext1,ps->ext2);
- X if ((fdsig = open(foo,O_WRONLY | O_CREAT | O_TRUNC,0600)) != -1)
- X {
- X (void) sprintf(foo,"/dev/tty%c%c",ext1,ext2);
- X if (write(fdsig,foo,11) == 11)
- X {
- X (void) close(fdsig);
- X return 0;
- X }
- X (void) close(fdsig);
- X }
- X return -1;
- X}
- X
- Xint pty_unset_sig(uid,ps)
- Xint uid;
- Xstruct pty_session *ps;
- X{
- X char foo[50];
- X
- X (void) sprintf(foo,"/usr/etc/pty/%d/sig.%c%c",uid,ps->ext1,ps->ext2);
- X return unlink(foo);
- X}
- END_OF_FILE
- if test 3786 -ne `wc -c <'util/sessutil.c'`; then
- echo shar: \"'util/sessutil.c'\" unpacked with wrong size!
- fi
- # end of 'util/sessutil.c'
- fi
- if test -f 'util/write.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'util/write.c'\"
- else
- echo shar: Extracting \"'util/write.c'\" \(2728 characters\)
- sed "s/^X//" >'util/write.c' <<'END_OF_FILE'
- X/* Public domain. */
- X
- X#include <sys/types.h>
- X#include <sys/timeb.h>
- X#include <sys/stat.h>
- X#include <sys/file.h>
- X#ifdef BSD
- X#include <limits.h>
- X#endif
- X#include <stdio.h>
- X#include <strings.h>
- X#include <utmp.h>
- X#include <pwd.h>
- X#include <time.h>
- X#include <ctype.h>
- Xextern unsigned short getuid();
- Xextern char *ttyname();
- Xextern long time();
- X#define PTYUTMP_FILE "/etc/utmp"
- X
- Xmain(argc,argv)
- Xint argc;
- Xchar *argv[];
- X{
- X register FILE *fi;
- X struct utmp ut;
- X char line[9];
- X int lines = 0;
- X char fntty[30];
- X int fd;
- X struct stat st;
- X char buf[500];
- X int offset;
- X char *username;
- X struct passwd *pw;
- X char hostname[64];
- X char *ttyn;
- X long t;
- X struct tm *tm;
- X char *s;
- X
- X if (argc < 2)
- X {
- X (void) fprintf(stderr,"Usage: write user [ttyname]\n");
- X (void) exit(1);
- X }
- X
- X if (!(pw = getpwuid((int) getuid())))
- X {
- X (void) fprintf(stderr,"write: who are you?\n");
- X (void) exit(1);
- X }
- X username = pw->pw_name;
- X
- X (void) gethostname(hostname,sizeof(hostname));
- X
- X if (!(ttyn = ttyname(2)))
- X {
- X (void) fprintf(stderr,"write: Can't find your tty\n");
- X (void) exit(1);
- X }
- X
- X t = time((long *) 0);
- X tm = localtime(&t);
- X
- X if (fi = fopen(PTYUTMP_FILE,"r"))
- X while (fread((char *) &ut,sizeof(ut),1,fi))
- X if (!strncmp(ut.ut_name,argv[1],8))
- X if ((argc == 2) || (!strncmp(ut.ut_line,argv[2],8)))
- X if (!lines)
- X {
- X (void) strncpy(line,ut.ut_line,8);
- X line[8] = '\0';
- X lines = 1;
- X }
- X else
- X lines++;
- X if (!lines)
- X {
- X if (argc == 2)
- X (void) fprintf(stderr,"write: %s not logged in\n",argv[1]);
- X else
- X (void) fprintf(stderr,"write: %s not logged in on tty %s\n",
- X argv[1],argv[2]);
- X (void) exit(1);
- X }
- X if (lines > 1)
- X (void) fprintf(stderr,
- X "write: %s logged in more than once ... writing to %s\n",
- X argv[1],line);
- X
- X (void) sprintf(fntty,"/dev/%s",line);
- X if ((fd = open(fntty,O_WRONLY)) == -1)
- X {
- X (void) fprintf(stderr,"write: Permission denied\n");
- X (void) exit(1);
- X }
- X
- X (void) sprintf(buf,"\nMessage from %s@%s on %s at %d:%02d ...\n",
- X username,hostname,ttyn + 5,tm->tm_hour,tm->tm_min);
- X (void) write(fd,buf,strlen(buf));
- X
- X (void) sprintf(buf,"%s: ",username);
- X offset = strlen(buf);
- X
- X while (fgets(buf + offset,sizeof(buf) - offset,stdin))
- X {
- X (void) fstat(fd,&st);
- X if (!(st.st_mode & 0020))
- X {
- X (void) fprintf(stderr,"write: Permission denied\n");
- X (void) exit(1);
- X }
- X for (s = buf;*s;s++)
- X if (((!isascii(*s) || !isprint(*s))) && (*s != '\n'))
- X *s = '^';
- X (void) write(fd,buf,strlen(buf));
- X (void) sleep(1);
- X }
- X
- X t = time((long *) 0);
- X tm = localtime(&t);
- X (void) sprintf(buf,"End of message from %s@%s on %s at %d:%02d\n",
- X username,hostname,ttyn + 5,tm->tm_hour,tm->tm_min);
- X (void) write(fd,buf,strlen(buf));
- X
- X (void) exit(0);
- X}
- END_OF_FILE
- echo shar: 1 control character may be missing from \"'util/write.c'\"
- if test 2728 -ne `wc -c <'util/write.c'`; then
- echo shar: \"'util/write.c'\" unpacked with wrong size!
- fi
- # end of 'util/write.c'
- fi
- if test -f 'util/xsessutil.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'util/xsessutil.c'\"
- else
- echo shar: Extracting \"'util/xsessutil.c'\" \(4232 characters\)
- sed "s/^X//" >'util/xsessutil.c' <<'END_OF_FILE'
- X/* Public domain. */
- X
- X#include "sessutil.h"
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <sys/file.h>
- X#ifdef BSD
- X#include <limits.h>
- X#endif
- X#include <stdio.h>
- Xextern char *ttyname();
- Xextern long lseek();
- Xextern char *getenv();
- X
- X/* Will have to change ttyn indices if DEVSTY changes. */
- X
- Xint pty_sessdir(uid)
- Xint uid;
- X{
- X char foo[50];
- X char *ho;
- X
- X if (!(ho = getenv("HOME")))
- X return -1;
- X (void) sprintf(foo,"%s/.pty/%d",ho,uid);
- X return chdir(foo);
- X}
- X
- Xint pty_get_sess(fd,uid,ps)
- Xint fd;
- Xint uid;
- Xstruct pty_session *ps;
- X{
- X char *ttyn;
- X
- X if (ttyn = ttyname(fd))
- X return pty_get_sessbyext(ttyn[8],ttyn[9],uid,ps);
- X return -1;
- X}
- X
- Xint pty_get_sessbyext(ext1,ext2,uid,ps)
- Xchar ext1;
- Xchar ext2;
- Xint uid;
- Xstruct pty_session *ps;
- X{
- X char foo[50];
- X int fdsess;
- X char *ho;
- X
- X if (!(ho = getenv("HOME")))
- X return -1;
- X
- X ps->ext1 = ext1;
- X ps->ext2 = ext2;
- X (void) sprintf(foo,"%s/.pty/%d/sess.%c%c",ho,uid,ps->ext1,ps->ext2);
- X if ((fdsess = open(foo,O_RDONLY)) != -1)
- X {
- X if ((read(fdsess,(char *) &ps->uid,sizeof(int)) == sizeof(int))
- X &&(read(fdsess,(char *) &ps->siglerpid,sizeof(int)) == sizeof(int))
- X &&(read(fdsess,(char *) &ps->masterpid,sizeof(int)) == sizeof(int))
- X &&(read(fdsess,(char *) &ps->slavepid,sizeof(int)) == sizeof(int)))
- X {
- X (void) close(fdsess);
- X return 0;
- X }
- X (void) close(fdsess);
- X }
- X return -1;
- X}
- X
- Xint pty_set_sess(fd,uid,ps)
- Xint fd;
- Xint uid;
- Xstruct pty_session *ps;
- X{
- X char *ttyn;
- X char foo[50];
- X int fdsess;
- X char *ho;
- X
- X if (!(ho = getenv("HOME")))
- X return -1;
- X
- X if (ttyn = ttyname(fd))
- X {
- X ps->ext1 = ttyn[8];
- X ps->ext2 = ttyn[9];
- X (void) sprintf(foo,"%s/.pty/%d/sess.%c%c",ho,uid,ps->ext1,ps->ext2);
- X if ((fdsess = open(foo,O_WRONLY)) != -1)
- X {
- X if ((write(fdsess,(char *) &ps->uid,sizeof(int)) == sizeof(int))
- X &&(write(fdsess,(char *) &ps->siglerpid,sizeof(int)) == sizeof(int))
- X &&(write(fdsess,(char *) &ps->masterpid,sizeof(int)) == sizeof(int))
- X &&(write(fdsess,(char *) &ps->slavepid,sizeof(int)) == sizeof(int)))
- X {
- X (void) close(fdsess);
- X return 0;
- X }
- X (void) close(fdsess);
- X }
- X }
- X return -1;
- X}
- X
- Xint pty_get_sessname(fd,uid,buf,len)
- Xint fd;
- Xint uid;
- Xchar *buf;
- Xint len;
- X{
- X char *ttyn;
- X char foo[50];
- X int fdsess;
- X int r;
- X char *ho;
- X
- X if (!(ho = getenv("HOME")))
- X return -1;
- X
- X if (ttyn = ttyname(fd))
- X {
- X (void) sprintf(foo,"%s/.pty/%d/sess.%c%c",ho,uid,ttyn[8],ttyn[9]);
- X if ((fdsess = open(foo,O_RDONLY)) != -1)
- X {
- X if (lseek(fdsess,(long) (4 * sizeof(int)),0) != (long) -1)
- X if ((r = read(fdsess,buf,len - 1)) > 0)
- X { /* could make that != -1. This way, default session is unnamed. */
- X buf[r] = '\0';
- X (void) close(fdsess);
- X return 0;
- X }
- X (void) close(fdsess);
- X }
- X }
- X return -1;
- X}
- X
- Xint pty_set_sessname(fd,uid,buf,len)
- Xint fd;
- Xint uid;
- Xchar *buf;
- Xint len;
- X{
- X char *ttyn;
- X char foo[50];
- X int fdsess;
- X char *ho;
- X
- X if (!(ho = getenv("HOME")))
- X return -1;
- X
- X if (ttyn = ttyname(fd))
- X {
- X (void) sprintf(foo,"%s/.pty/%d/sess.%c%c",ho,uid,ttyn[8],ttyn[9]);
- X if ((fdsess = open(foo,O_WRONLY)) != -1)
- X {
- X if (lseek(fdsess,(long) (4 * sizeof(int)),0) != (long) -1)
- X if (write(fdsess,buf,len) != -1)
- X {
- X (void) close(fdsess);
- X return 0;
- X }
- X (void) close(fdsess);
- X }
- X }
- X return -1;
- X}
- X
- Xint pty_get_rebyext(ext1,ext2,uid)
- Xchar ext1;
- Xchar ext2;
- Xint uid;
- X{
- X char foo[50];
- X struct stat st;
- X char *ho;
- X
- X if (!(ho = getenv("HOME")))
- X return -1;
- X
- X (void) sprintf(foo,"%s/.pty/%d/re.%c%c",ho,uid,ext1,ext2);
- X return stat(foo,&st);
- X}
- X
- Xint pty_set_sig(ext1,ext2,uid,ps)
- Xchar ext1;
- Xchar ext2;
- Xint uid;
- Xstruct pty_session *ps;
- X{
- X char foo[50];
- X int fdsig;
- X char *ho;
- X
- X if (!(ho = getenv("HOME")))
- X return -1;
- X
- X (void) sprintf(foo,"%s/.pty/%d/sig.%c%c",ho,uid,ps->ext1,ps->ext2);
- X if ((fdsig = open(foo,O_WRONLY | O_CREAT | O_TRUNC,0600)) != -1)
- X {
- X (void) sprintf(foo,"/dev/tty%c%c",ext1,ext2);
- X if (write(fdsig,foo,11) == 11)
- X {
- X (void) close(fdsig);
- X return 0;
- X }
- X (void) close(fdsig);
- X }
- X return -1;
- X}
- X
- Xint pty_unset_sig(uid,ps)
- Xint uid;
- Xstruct pty_session *ps;
- X{
- X char foo[50];
- X char *ho;
- X
- X if (!(ho = getenv("HOME")))
- X return -1;
- X
- X (void) sprintf(foo,"%s/.pty/%d/sig.%c%c",ho,uid,ps->ext1,ps->ext2);
- X return unlink(foo);
- X}
- END_OF_FILE
- if test 4232 -ne `wc -c <'util/xsessutil.c'`; then
- echo shar: \"'util/xsessutil.c'\" unpacked with wrong size!
- fi
- # end of 'util/xsessutil.c'
- fi
- echo shar: End of archive 4 \(of 6\).
- cp /dev/null ark4isdone
- MISSING=""
- for I in 1 2 3 4 5 6 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 6 archives.
- rm -f ark[1-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
- exit 0 # Just in case...
- --
- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
- Use a domain-based address or give alternate paths, or you may lose out.
-